package pl.register.android.activities.correlation;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import com.actionbarsherlock.app.SherlockFragment;
import pl.register.android.R;
import pl.register.android.activities.correlation.builder.*;
import pl.register.android.activities.correlation.logic.AsyncCorrelationLoader;
import pl.register.android.activities.correlation.logic.Correlation;
import pl.register.android.activities.correlation.logic.CorrelationStudentsPresenter;
import pl.register.android.activities.correlation.ui.CorrelationHolidayListAdapter;
import pl.register.android.activities.correlation.ui.CorrelationListAdapter;
import pl.register.android.activities.correlation.ui.CorrelationSpinnerAdapter;
import pl.register.android.activities.correlation.ui.CorrelationView;
import pl.register.android.course.dialog.CreatorNextCourseDialogBuilder;
import pl.register.android.course.dialog.NotFoundPreviousCourseDialogBuilder;
import pl.register.android.course.factory.CourseFactory;
import pl.register.android.course.factory.CreatorCourseMonitoring;
import pl.register.android.database.exception.CanNotAddLessonProgramException;
import pl.register.android.database.exception.NotFoundCourseException;
import pl.register.android.course.Course;
import pl.register.android.database.DatabaseAdapter;
import pl.register.android.database.exception.NotFoundNextLessonProgramException;
import pl.register.android.group.StudentsGroup;
import pl.register.android.lesson.LessonProgram;
import pl.register.android.lesson.TagLesson;
import pl.register.android.preferences.ResotorePreferences;
import pl.register.android.student.Student;
import pl.register.android.year.Year;
import pl.register.android.year.YearType;

import java.util.*;

/**
 * @author Mateusz Strzelecki
 * @since 2013-04-19
 */
public class CorrelationFragment extends SherlockFragment
        implements CorrelationView, AdapterView.OnItemSelectedListener, CompoundButton.OnCheckedChangeListener, View.OnClickListener, CreatorCourseMonitoring {

    private ImageButton imageBtnPrevious;

    private ImageButton imageBtnNext;

    private TextView tvTitle;

    private TextView tvStartYear;

    private TextView tvEndYear;

    private RadioButton rbOctoberTag;

    private RadioButton rbNovemberTag;

    private RadioButton rbDecemberTag;

    private RadioButton rbJanuaryTag;

    private RadioButton rbFebruaryTag;

    private RadioButton rbMarchTag;

    private RadioButton rbAprilTag;

    private RadioButton rbMayTag;

    private RadioButton rbJuneTag;

    private RadioButton rbHoliday1Tag;

    private RadioButton rbHoliday2Tag;


    private View vCorrelationTable;

    private View vHolidayCorrelationTable;

    private View vHeaders;

    private View vHolidayHeaders;

    private Button btnAddStudent;

    private Button btnAddProgramLesson;

    private Button btnHolidayAddProgramLesson;

    private ListView lvCorrelation;

    private ListView lvHolidayCorrelation;

    private Spinner sCorrelations;

    private Spinner sHolidayCorrelations;

    private Map<TagLesson, RadioButton> rbTagsMap;


    private DatabaseAdapter databaseAdapter;

    private CorrelationStudentsPresenter presenter;

    private CorrelationListAdapter listAdapter;

    private CorrelationHolidayListAdapter holidayListAdapter;

    private CorrelationSpinnerAdapter spinnerAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        databaseAdapter = new DatabaseAdapter(getActivity());
        databaseAdapter.open();
        presenter = new CorrelationStudentsPresenter(databaseAdapter, this);
        View contentLayout = inflater.inflate(R.layout.correlation_layout, container, false);
        registerViews(contentLayout, inflater);
        setupContent();

        return contentLayout;
    }

    @Override
    public void onResume() {
        super.onResume();
        Course course = ResotorePreferences.getCourse(getActivity());
        new AsyncCorrelationLoader(getActivity(), this, presenter, course).execute();
    }

    private void registerViews(View content, LayoutInflater inflater) {
        vCorrelationTable = content.findViewById(R.id.correlation_table);
        vHolidayCorrelationTable = content.findViewById(R.id.holiday_correlation_table);
        imageBtnPrevious = (ImageButton) content.findViewById(R.id.previous_button);
        imageBtnNext = (ImageButton) content.findViewById(R.id.next_button);
        tvTitle = (TextView) content.findViewById(R.id.title_table_text_view);
        tvStartYear = (TextView) content.findViewById(R.id.start_year_date_text_view);
        tvEndYear = (TextView) content.findViewById(R.id.end_year_date_text_view);
        rbOctoberTag = (RadioButton) content.findViewById(R.id.october_tag_radio_button);
        rbNovemberTag = (RadioButton) content.findViewById(R.id.november_tag_radio_button);
        rbDecemberTag = (RadioButton) content.findViewById(R.id.december_tag_radio_button);
        rbJanuaryTag = (RadioButton) content.findViewById(R.id.january_tag_radio_button);
        rbFebruaryTag = (RadioButton) content.findViewById(R.id.february_tag_radio_button);
        rbMarchTag = (RadioButton) content.findViewById(R.id.march_tag_radio_button);
        rbAprilTag = (RadioButton) content.findViewById(R.id.april_tag_radio_button);
        rbMayTag = (RadioButton) content.findViewById(R.id.may_tag_radio_button);
        rbJuneTag = (RadioButton) content.findViewById(R.id.june_tag_radio_button);
        rbHoliday1Tag = (RadioButton) content.findViewById(R.id.holiday_I_tag_radio_button);
        rbHoliday2Tag = (RadioButton) content.findViewById(R.id.holiday_II_tag_radio_button);

        vHeaders = content.findViewById(R.id.correlation_headers);
        vHolidayHeaders = content.findViewById(R.id.holiday_correlation_headers);
        View footerView = inflater.inflate(R.layout.list_footer_correlation_add_student, null, false);
        lvCorrelation = (ListView) content.findViewById(R.id.correlation_list_view);
        lvHolidayCorrelation = (ListView) content.findViewById(R.id.holiday_correlation_list_view);
        lvHolidayCorrelation.addFooterView(footerView);
        lvCorrelation.addFooterView(footerView);
        btnAddProgramLesson = (Button) content.findViewById(R.id.add_lesson_program_button);
        btnHolidayAddProgramLesson = (Button) content.findViewById(R.id.holiday_add_lesson_program_button);
        btnAddStudent = (Button) footerView.findViewById(R.id.add_student_button);
        sCorrelations = (Spinner) content.findViewById(R.id.correlations_spinner);
        sHolidayCorrelations = (Spinner) content.findViewById(R.id.holiday_correlations_spinner);
    }

    private void setupContent() {
        listAdapter = new CorrelationListAdapter(getActivity(), presenter, this);
        lvCorrelation.setAdapter(listAdapter);
        holidayListAdapter = new CorrelationHolidayListAdapter(getActivity(), presenter, this);
        lvHolidayCorrelation.setAdapter(holidayListAdapter);

        spinnerAdapter = new CorrelationSpinnerAdapter(getActivity());
        sCorrelations.setAdapter(spinnerAdapter);
        sHolidayCorrelations.setAdapter(spinnerAdapter);

        imageBtnPrevious.setOnClickListener(this);
        imageBtnNext.setOnClickListener(this);
        btnAddStudent.setOnClickListener(this);
        btnAddProgramLesson.setOnClickListener(this);
        btnHolidayAddProgramLesson.setOnClickListener(this);

        rbTagsMap = new HashMap<TagLesson, RadioButton>();
        registerRadioButton(rbOctoberTag, TagLesson.OCTOBER);
        registerRadioButton(rbNovemberTag, TagLesson.NOVEMBER);
        registerRadioButton(rbDecemberTag, TagLesson.DECEMBER);
        registerRadioButton(rbJanuaryTag, TagLesson.JANUARY);
        registerRadioButton(rbFebruaryTag, TagLesson.FEBRUARY);
        registerRadioButton(rbMarchTag, TagLesson.MARCH);
        registerRadioButton(rbAprilTag, TagLesson.APRIL);
        registerRadioButton(rbMayTag, TagLesson.MAY);
        registerRadioButton(rbJuneTag, TagLesson.JUNE);
        registerRadioButton(rbHoliday1Tag, TagLesson.HOLIDAY_I);
        registerRadioButton(rbHoliday2Tag, TagLesson.HOLIDAY_II);
    }

    private void registerRadioButton(RadioButton radioButton, TagLesson tagLesson) {
        rbTagsMap.put(tagLesson, radioButton);
        radioButton.setText(tagLesson.getName());
        radioButton.setTag(tagLesson);
        radioButton.setOnCheckedChangeListener(this);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        Correlation correlation = spinnerAdapter.getItem(position);
        presenter.changeCorrelation(getActivity(), correlation);
        sHolidayCorrelations.setSelection(position);
        sCorrelations.setSelection(position);
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isSelected) {
        if (!isSelected) {
            return;
        }
        switch (buttonView.getId()) {
            case R.id.october_tag_radio_button:
            case R.id.november_tag_radio_button:
            case R.id.december_tag_radio_button:
            case R.id.january_tag_radio_button:
            case R.id.february_tag_radio_button:
            case R.id.march_tag_radio_button:
            case R.id.april_tag_radio_button:
            case R.id.may_tag_radio_button:
            case R.id.june_tag_radio_button:
            case R.id.holiday_I_tag_radio_button:
            case R.id.holiday_II_tag_radio_button:
                TagLesson tagLesson = (TagLesson) buttonView.getTag();
                presenter.changeTagLesson(getActivity(), tagLesson);
                break;
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.add_student_button:
                if (presenter.correlationIsSelected()) {
                    showDialogStudentChooser();
                }
                break;
            case R.id.holiday_add_lesson_program_button:
            case R.id.add_lesson_program_button:
                if (presenter.correlationIsSelected()) {
                    try {
                        presenter.addNextLessonProgram();
                    } catch (NotFoundNextLessonProgramException e) {
                        Toast.makeText(getActivity(), "Wykorzystano już wszystkie zajęcia z programu.", Toast.LENGTH_LONG).show();
                    } catch (CanNotAddLessonProgramException e) {
                        Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show();
                    }
                }
                break;
            case R.id.next_button:
                try {
                    presenter.rebuildForNextCourse(getActivity());
                } catch (NotFoundCourseException e) {
                    showCreateCourseDialog();
                }
                break;
            case R.id.previous_button:
                try {
                    presenter.rebuildForPreviousCourse(getActivity());
                } catch (NotFoundCourseException e) {
                    showNotFoundCourseDialog();
                }
                break;
        }
    }

    @Override
    public void refreshTitle(TagLesson tag, Course course) {
        RadioButton radioButton = rbTagsMap.get(tag);
        radioButton.setChecked(true);
        tvTitle.setText(tag.getNameWithYear(course));
    }

    @Override
    public void populateTable(Correlation correlation) {
        Year year = correlation.getYear();
        if (year.getType().equals(YearType.HOLIDAY_I_YEAR) || year.getType().equals(YearType.HOLIDAY_II_YEAR)) {
            vCorrelationTable.setVisibility(View.GONE);
            vHolidayCorrelationTable.setVisibility(View.VISIBLE);
            sCorrelations.setOnItemSelectedListener(null);
            sHolidayCorrelations.setOnItemSelectedListener(this);
            holidayListAdapter.refreshItems(correlation);
        } else {
            vCorrelationTable.setVisibility(View.VISIBLE);
            vHolidayCorrelationTable.setVisibility(View.GONE);
            sCorrelations.setOnItemSelectedListener(this);
            sHolidayCorrelations.setOnItemSelectedListener(null);
            listAdapter.refreshItems(correlation);
        }
    }

    public void populateCourse(String startYear, String endYear) {
        tvStartYear.setText(startYear);
        tvEndYear.setText(endYear);
    }

    @Override
    public void populateCorrelations(List<Correlation> correlations) {
        spinnerAdapter.refreshItems(correlations);
    }

    @Override
    public Correlation settleCorrelationBy(YearType yearType) {
        Correlation selectCorrelation = null;
        int position = spinnerAdapter.getIndexBy(yearType);
        if (position >= 0) {
            sCorrelations.setSelection(position);
            selectCorrelation = spinnerAdapter.getItem(position);
        }
        return selectCorrelation;
    }

    @Override
    public void startStudentProfileActivity(Student student, Year year) {
        presenter.goToProfile(getActivity(), student, year);
    }

    @Override
    public void insertedNewCourse(Course course) {
        //TODO utworzono kurs na kolejny rok
    }

    public void showDialogStudentChooser() {
        new StudentChooserDialogBuilder(getActivity(), presenter).create().show();
    }

    @Override
    public void showDeleteStudentConfirmationDialog(Student toRemove, StudentsGroup studentGroup) {
        new DeleteStudentFromGroupConfirmationDialogBuilder(getActivity(), toRemove, studentGroup, presenter).create().show();
    }

    @Override
    public void showDeleteLessonProgramConfirmationDialog(LessonProgram toRemove) {
        new DeleteLessonProgramConfirmationDialogBuilder(getActivity(), toRemove, presenter).create().show();
    }

    @Override
    public void showClassesScheduleDialog(LessonProgram lessonProgram, Button btnSchedule) {
        new ClassesDateEditorDialog(getActivity(), lessonProgram, presenter, btnSchedule).show();
    }

    @Override
    public void showHomeworkScheduleDialog(LessonProgram lessonProgram, Button btnSchedule) {
        new HomeworkDateEditorDialog(getActivity(), lessonProgram, presenter, btnSchedule).show();
    }

    private void showCreateCourseDialog() {
        AlertDialog alertDialog = new CreatorNextCourseDialogBuilder(getActivity(), this).create();
        alertDialog.show();
        alertDialog.getWindow().setLayout(600, 400);
    }

    private void showNotFoundCourseDialog() {
        AlertDialog alertDialog = new NotFoundPreviousCourseDialogBuilder(getActivity()).create();
        alertDialog.show();
        alertDialog.getWindow().setLayout(600, 400);
    }

    @Override
    public void showLoadLastCourseDialog(Course course) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Brak kursu");
        builder.setMessage("Niestety nie udało się znaleźć kursu " + course.getStartYear() + "/" + course.getEndYear()
                + " Czy chcesz pobrać ostatni?");
        builder.setNegativeButton(R.string.btn_name_no, null);
        builder.setPositiveButton(R.string.btn_name_yes, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Course lastCourse = CourseFactory.getLastCourse(databaseAdapter);
                new AsyncCorrelationLoader(getActivity(), CorrelationFragment.this, presenter, lastCourse).execute();
            }
        });
        builder.create().show();
    }

    @Override
    public View getHeadersView() {
        return vHeaders;
    }

    @Override
    public View getHolidayHeadersView() {
        return vHolidayHeaders;
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (databaseAdapter != null) {
            databaseAdapter.close();
        }
    }
}